#!/usr/bin/env python
import os
import fnmatch


#def walk(root='.', recurse=True, pattern='*'):
    #"""Generator for walking a directory tree.

    #Starts at specified root folder, returning files
    #that match our pattern. Optionally will also
    #recurse through sub-folders.
    #"""
    #for path, subdirs, files in os.walk(root):
        #for name in files:
            #if fnmatch.fnmatch(name, pattern):
                #yield os.path.join(path, name)
        #if not recurse:
            #break

## walk(root, recurse, '*.py')
#def codeReport(files, recurse=True, code_delimiter=';', line_delimiter=os.linesep, comment_starter='#', stream_starter='"""', stream_ender='"""'):
    #"""Analyzes a list of files, returning a lines of code report."""
    #_mode = "line" # line, or stream mode for when multiline comments are used.
    #_stream_starter_index = 0

    #count = dict()
    #count['lines'] = 0
    #count['codes'] = 0
    #count['codelines'] = 0
    #count['comments'] = 0
    #count['linecomments'] = 0
    #count['blanks'] = 0
    #count['streamcomments'] = 0
    #count['streamlines'] = 0
    #count['files'] = dict()
    #for f in files:
        #count['files'][f] = dict()
        #count['files'][f]['lines'] = 0
        #count['files'][f]['codes'] = 0
        #count['files'][f]['comments'] = 0
        #count['files'][f]['linecomments'] = 0
        #count['files'][f]['blanks'] = 0
        #count['files'][f]['streamcomments'] = 0
        #count['files'][f]['streamlines'] = 0

        #with open(f) as f:
            #for line in f:
                #line = line.strip()
                #count['lines'] += 1
                #count['files'][f]['lines'] += 1
                #if _mode == 'stream':
                    #count['files'][f]['streamlines'] += 1
                    #count['streamlines'] += 1
                    #_end_stream = stream_enders[_stream_starter_index]
                    #if line.count(_end_stream) > 0:
                        #_mode = 'line'
                        #count['files'][f]['comments'] += 1
                        #count['files'][f]['streamcomments'] += 1
                        #count['comments'] += 1
                        #count['streamcomments'] += 1
                        #line = line[line.find(stream_ender):].strip()
                        #if line == '':
                            #continue
                #while True:
                    #i = line.find(stream_starter)
                    #if i == 0:
                        #_mode = 'stream'
                        #count['files'][f]['comments'] += 1
                        #count['files'][f]['streamcomments'] += 1
                        #count['comments'] += 1
                        #count['streamcomments'] += 1
                    #elif i > 0:
                        #_mode = 'stream'
                        #count['files'][f]['comments'] += 1
                        #count['files'][f]['streamcomments'] += 1
                        #count['files'][f]['codes'] += 1
                        #count['comments'] += 1
                        #count['streamcomments'] += 1
                        #count['codes'] += 1
                    #else:



                #i = line.find(comment_starter)
                #if i == 0:
                    #count['files'][f]['comments'] += 1
                    #count['files'][f]['linecomments'] += 1
                    #count['comments'] += 1
                    #count['linecomments'] += 1
                    #continue
                #elif i > 0:
                    #count['files'][f]['comments'] += 1
                    #count['files'][f]['linecomments'] += 1
                    #count['files'][f]['codes'] += 1
                    #count['comments'] += 1
                    #count['linecomments'] += 1
                    #count['codes'] += 1

def changeRange(X, (A, B), (C, D)):
    """Given X on the range A-B, return Y of relevant value on new range C-D"""
    return (((C - D) * X) + (B * C) + (C * D)) / (A - B)

class TriListError(Exception):
    pass

class TriListTree(object):
    def __init__(self):
        self.pre = list()
        self.main = list()
        self.post = list()

    def append(self, item, container):
        if container == "pre":
            self.pre.append(item)
        elif container == "main":
            self.main.append(item)
        elif container == "post":
            self.post.append(item)
        else:
            raise TriListError("Incorrect container specified")

    def remove(self, item, container):
        if container == "pre":
            self.pre.remove(item)
        elif container == "main":
            self.main.remove(item)
        elif container == "post":
            self.post.remove(item)
        else:
            raise TriListError("Incorrect container specified")

    def remove_all(self, container, item=None):
        if container == "pre":
            container = self.pre
        elif container == "main":
            container = self.main
        elif container == "post":
            container = self.post
        else:
            raise TriListError("Incorrect container specified")
        # remove everything in the list.
        if item is None:
            num_removed = len(container)
            container = list()
        # remove all instances of item from the list
        else:
            num_removed = container.count(item)
            for i in num_removed:
                container.remove(item)
        return num_removed

    def iterate(self):
        for item in self.pre:
            yield item
        for item in self.main:
            yield item
        for item in self.post:
            yield item
